package com.sxhuayuan.parking.service.impl;

import com.sxhuayuan.parking.compenent.Filter;
import com.sxhuayuan.parking.compenent.Message;
import com.sxhuayuan.parking.compenent.Page;
import com.sxhuayuan.parking.compenent.Pageable;
import com.sxhuayuan.parking.compenent.shiro.AccountType;
import com.sxhuayuan.parking.compenent.shiro.Principal;
import com.sxhuayuan.parking.compenent.web.RespMessage;
import com.sxhuayuan.parking.dao.BaseDao;
import com.sxhuayuan.parking.dao.ParkingLotUserDao;
import com.sxhuayuan.parking.entity.Agent;
import com.sxhuayuan.parking.entity.ParkingLotUser;
import com.sxhuayuan.parking.exception.MyException;
import com.sxhuayuan.parking.service.ParkingLotUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.List;
import java.util.Objects;

/**
 * @author 何龙
 * @create 2019-04-19 10:42
 */
@Service("parkingLotUserServiceImpl")
public class ParkingLotUserServiceImpl extends BaseServiceImpl<ParkingLotUser, Long> implements ParkingLotUserService {
	@Autowired
	ParkingLotUserDao dao;

	@Override
	public BaseDao<ParkingLotUser, Long> getDAO() {
		return dao;
	}

	@Override
	@Transactional(readOnly = true)
	public ParkingLotUser findByUsername(String username) {
		return dao.findByUsername(username);
	}

	@Override
	@Transactional(readOnly = true)
	public boolean usernameExists(String username) {
		return dao.count((Root<ParkingLotUser> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) -> criteriaBuilder.equal(root.get("username"), username)) > 0;
	}

	@Override
	@Transactional(readOnly = true)
	public ParkingLotUser getCurrent() {
		Subject subject = SecurityUtils.getSubject();
		if (subject != null && subject.getPrincipal() != null) {
			Principal principal = (Principal) subject.getPrincipal();
			if (principal.getType() == AccountType.parkinglot) {
				return dao.findById(principal.getId()).get();
			}
		}
		return null;

	}

	@Override
	@Transactional(readOnly = true)
	public Page<ParkingLotUser> findPage(Pageable pageable, Agent agent) {

		StringBuilder sb = new StringBuilder("select p from ParkingLotUser p join AgentRelation r on p.parkingLot.agent=r.child where r.parent.id=").append(agent.getId());
		List<Filter> filters = pageable.getFilters();
		String istartTime = null;
		String iendTime = null;
		if (filters != null) {
			for (Filter filter : filters) {
				switch (filter.getProperty()) {
				case "istartTime":
					istartTime = (String) filter.getValue();
					break;
				case "iendTime":
					iendTime = (String) filter.getValue();
					break;
				default:
					sb = setCondition(sb, filter);
					break;
				}
			}
		}

		if (istartTime != null && !istartTime.equals("") && iendTime != null && !iendTime.equals("")) {
			sb.append(" and p.createDate >= '").append(istartTime).append("' and p.createDate <= '").append(iendTime).append("' ");
		}

		sb.append(" order by p.id desc");
		return findPage(sb.toString(), sb.toString().replace("select p", "select count(p.id)"), pageable.getPageSize(), pageable.getPageNumber());

	}

	/** 组装查询条件 */
	private StringBuilder setCondition(StringBuilder sb, Filter filter) {
		if (filter.getProperty() == null || filter.getProperty().equals("") || filter.getValue() == null || filter.getValue().equals("")) {
			return sb;
		}
		switch (filter.getProperty()) {

		case "name": {
			return sb.append(" and p.name='").append(filter.getValue()).append("' ");
		}

		case "username": {
			return sb.append(" and p.username='").append(filter.getValue()).append("' ");
		}

		case "isEnabled": {
			return sb.append(" and p.isEnabled='").append(filter.getValue()).append("' ");
		}

		case "isLocked": {
			return sb.append(" and p.isLocked='").append(filter.getValue()).append("' ");
		}

		case "parkingLotName": {
			return sb.append(" and p.parkingLot.name='").append(filter.getValue()).append("' ");
		}

		default:
			return sb;
		}

	}

	@Override
	@Transactional(readOnly = true)
	public void onIsLockedAndEnabled(Long id, String type, Boolean value) {
		ParkingLotUser parkingLotUser = findOne(id);
		if (Objects.isNull(parkingLotUser)) {
			throw new MyException(RespMessage.Status.VALID_ERR, Message.FORM_VALID_FAIL);
		}
		if ("Locked".equals(type)) {
			parkingLotUser.setIsLocked(value);
		}
		if ("Enabled".equals(type)) {
			parkingLotUser.setIsEnabled(value);
		}
		dao.save(parkingLotUser);
	}
}
